/*
 * PersistenceAdditive.java
 *
 * Created on June 10, 2007, 4:07 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package afterburner.fuel.persistence;

import afterburner.fuel.annotations.PersistenceFuel;
import afterburner.jsp.Base;
import afterburner.jsp.JSP;
import afterburner.jsp.annotations.DefaultAction;
import afterburner.jsp.fuel.FuelAdditive;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;

/**
 *
 * @author aris
 */
public class PersistenceAdditive implements FuelAdditive {

    /**
     * Creates a new instance of PersistenceAdditive
     */
    public PersistenceAdditive() {
    }

    /**
     * Looks for a context parameter named "persistence".
     * The value is the name of a persistence unit.
     */
    public void contextInitialized(ServletContext sc) {
        String persistenceString = sc.getInitParameter("persistence");
        Map<String, EntityManagerFactory> entityManagerFactories = new Hashtable();
        if (persistenceString != null && persistenceString.trim().length() > 0) {
            String persistenceNames[] = persistenceString.split(",");
            for (String pn : persistenceNames) {
                try {
                    EntityManagerFactory emf = Persistence.createEntityManagerFactory(pn);
                    if (emf != null) {
                        entityManagerFactories.put(pn, emf);
                    }
                } catch (Exception e) {
                    sc.log(e.getMessage());
                }
            }
        }
        sc.setAttribute("persistence", entityManagerFactories);
    }

    public void contextDestroyed(ServletContext sc) {

        Map<String, EntityManagerFactory> entityManagerFactories = (Map) sc.getAttribute("persistence");
        Collection collection = entityManagerFactories.values();
        Iterator<EntityManagerFactory> iterator = collection.iterator();
        while (iterator.hasNext()) {
            EntityManagerFactory emf = iterator.next();
            try {
                emf.close();
            } catch (Exception e) {
                sc.log(e.getMessage());
            }
        }
    }

    public void preJSP(Base baseJSP) {
        ServletContext sc = baseJSP.getServletConfig().getServletContext();
        JSP jsp = (JSP) baseJSP;
        Map<String, EntityManagerFactory> map = (Map) sc.getAttribute("persistence");
        if (map != null) {
            Method methods[] = jsp.getClass().getMethods();
            for (Method method : methods) {
                PersistenceFuel pf = method.getAnnotation(PersistenceFuel.class);
                if (pf != null) {
                    EntityManagerFactory emf = map.get(pf.value());
                    if (emf != null) {
                        try {
                            EntityManager em = emf.createEntityManager();
                            method.invoke(baseJSP, em);
                            em.getTransaction().begin();
                            baseJSP.getRequest().setAttribute("X_PERSISTENCE_"+pf.value(), em);
                        } catch (Exception e) {
                            baseJSP.getServletConfig().getServletContext().log("An exeption occurred while creating the Entity Manager for " + pf.value() + " " + e.getMessage());
                            e.printStackTrace();
                        }
                    } else {
                        baseJSP.log("An Entity Manager for " + pf.value() + " could not be found.");
                    }
                }
            }
        }
    }

    public void postJSP(Base baseJSP) {
        ServletContext sc = baseJSP.getServletConfig().getServletContext();
        JSP jsp = (JSP) baseJSP;
        Method methods[] = jsp.getClass().getMethods();
        for (Method method : methods) {
            PersistenceFuel pf = method.getAnnotation(PersistenceFuel.class);
            if (pf != null) {
                try {
                    EntityManager em = (EntityManager)baseJSP.getRequest().getAttribute("X_PERSISTENCE_"+pf.value());
                    
                    method.invoke(baseJSP, (EntityManager) null);
                    if(em != null){
                        EntityTransaction et = em.getTransaction();
                        if(et.isActive())et.commit();
                        em.close();
                    }
                } catch (Exception e) {
                    baseJSP.getServletConfig().getServletContext().log("An exeption occurred while closing the Entity Manager for " + pf.value() + " " + e.getMessage());
                    e.printStackTrace();
                }
            }
        }
    }
}
